package com.jackrain.nea.wms.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.jackrain.nea.config.Resources;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.wms.api.BaseSaveCmd;
import com.jackrain.nea.sys.CommandAdapter;
import com.jackrain.nea.util.ValueHolder;
import com.jackrain.nea.web.query.DefaultWebEvent;
import com.jackrain.nea.web.query.QuerySession;
import com.jackrain.nea.web.service.QueryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.sql.Timestamp;
import java.util.*;


@Slf4j
@Component
@Service(protocol = "dubbo", validation = "true", version="1.0", group = "wms")
public class BaseSaveCmdImpl extends CommandAdapter implements BaseSaveCmd {

    @Autowired
    private QueryService queryService;

    @Override
    public ValueHolder execute(QuerySession querySession) throws NDSException {
        ValueHolder vh = new ValueHolder();
        DefaultWebEvent event = querySession.getEvent();
        JSONObject param = JSON.parseObject(JSON.toJSONStringWithDateFormat(event.getParameterValue("param"),"yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue),Feature.OrderedField);
        log.info("BaseSaveCmdImpl--param-->{}",param);

        JSONObject fixColumn = param.getJSONObject("fixcolumn");
        JSONObject fkColumn = param.getJSONObject("fkcolumn");
        String mTable = param.getString("table");

        // 当前系统时间
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        // 获取主表json
        JSONObject jo = fixColumn.getJSONObject(mTable);
        // 获取objid判断 新增或更新
        Long objid = param.getLong("objid");
        if (objid < 0) {
            // 新增主表
            objid = insertMtable(jo, querySession, timestamp,mTable);
        } else {
            // 更新主表
            if (null != jo && jo.size()>0) {
                for (String key: jo.keySet()) {
                    if (jo.get(key).equals("null")){
                        jo.put(key,null);
                    }
                }
                updateMtable(jo, querySession, timestamp, objid, mTable);
            }else{
                // 更新主表修改人和修改时间
                jo = new JSONObject();
                updateMtable(jo, querySession, timestamp, objid, mTable);
            }
        }

        // 获取子表json
        // 子表错误信息返回json
        JSONArray dataArrayJson = new JSONArray();
        Set<String> refTables = fixColumn.keySet();
        refTables.remove(mTable);


        for (String itemTable : refTables) {
            JSONArray joItem = fixColumn.getJSONArray(itemTable);
            String fkKey = fkColumn.getString(itemTable);

            for (int i = 0; i < joItem.size(); i++) {
                if (joItem.getJSONObject(i).getLong("ID") < 0) {
                    // 像明细表参数中加入外键key、value
                    joItem.getJSONObject(i).put(fkKey,objid);
                    // 新增子表
                    JSONObject jsonObject = insertStable(itemTable, joItem, querySession, timestamp, i);
                    if (jsonObject.size() > 0) {
                        dataArrayJson.add(jsonObject);
                    }
                } else {
                    // 更新子表
                    for (String key: joItem.getJSONObject(i).keySet()) {
                        if (joItem.getJSONObject(i).get(key).equals("null")){
                            joItem.getJSONObject(i).put(key,null);
                        }
                    }
                    JSONObject jsonObject = updateStable(itemTable, joItem, querySession, timestamp, i);
                    if (jsonObject.size() > 0) {
                        dataArrayJson.add(jsonObject);
                    }
                }
            }
        }


        JSONObject dataJson = new JSONObject();
        dataJson.put("objid",objid);
        dataJson.put("tablename",mTable);


        if(dataArrayJson.size() > 0){
            if (objid < 0){
                dataJson.put("error",dataArrayJson);
                vh.put("data", dataJson);
            }else{
                vh.put("data", dataArrayJson);
            }
            vh.put("code",-1);
            vh.put("message",Resources.getMessage("失败",querySession.getLocale()));
        }else{
            vh.put("data", dataJson);
            vh.put("code",0);
            vh.put("message",Resources.getMessage("成功",querySession.getLocale()));
        }
        log.info("BaseSaveCmdImpl--vh-->{}",vh);
        return vh;
    }

    /**
     * 新增主表
     * @param insertKeys 主表参数
     * @param querySession querySession
     * @param timestamp 系统时间
     * @param mTable 主表名称
     * @return Long
     */
    private Long insertMtable(JSONObject insertKeys,QuerySession querySession,Timestamp timestamp,String mTable){
        // 新增主表
        insertKeys.put("AD_CLIENT_ID",Integer.valueOf(querySession.getUser().getClientId()).longValue());
        insertKeys.put("AD_ORG_ID",Integer.valueOf(querySession.getUser().getOrgId()).longValue());
        insertKeys.put("MODIFIERID", querySession.getUser().getId().longValue());
        insertKeys.put("MODIFIEDDATE",timestamp);
        insertKeys.put("OWNERID", querySession.getUser().getId().longValue());
        insertKeys.put("CREATIONDATE",timestamp);
        // 执行mapper新增
        HashMap mTableMap = new HashMap();
        mTableMap.put("tableName",mTable);
        mTableMap.put("insertKeys",insertKeys);
        return queryService.commandInsert(mTableMap);
    }

    /**
     * 新增子表
     * @param joItem 明细表参数
     * @param querySession querySession
     * @param timestamp 系统时间
     * @param i 当前循环序号
     * @return JSONObject
     */
    private JSONObject insertStable(String tableName,JSONArray joItem,QuerySession querySession,Timestamp timestamp,int i){

        JSONObject dataJson = new JSONObject();
        JSONObject insertKeys = joItem.getJSONObject(i);

        try {
            // 新增明细表
            insertKeys.put("AD_CLIENT_ID",Integer.valueOf(querySession.getUser().getClientId()).longValue());
            insertKeys.put("AD_ORG_ID",Integer.valueOf(querySession.getUser().getOrgId()).longValue());
            //外键关联字段
            insertKeys.put("MODIFIERID", querySession.getUser().getId().longValue());
            insertKeys.put("MODIFIEDDATE",timestamp);
            insertKeys.put("OWNERID", querySession.getUser().getId().longValue());
            insertKeys.put("CREATIONDATE",timestamp);
            // 执行mapper新增
            HashMap sTableMap = new HashMap();
            sTableMap.put("tableName",tableName);
            sTableMap.put("insertKeys",insertKeys);
            queryService.commandInsert(sTableMap);
        }catch (NDSException e){
            // 将错误信息存入dataArrayJson中
            dataJson = getData(e);
        }

        return dataJson;
    }

    /**
     * 更新主表
     * @param setKeys 主表参数
     * @param querySession querySession
     * @param timestamp 系统时间
     * @param objid 主表ID
     * @param mTable 主表表名
     */
    private void updateMtable(JSONObject setKeys,QuerySession querySession,Timestamp timestamp,Long objid,String mTable){

        setKeys.put("MODIFIERID", querySession.getUser().getId().longValue());
        setKeys.put("MODIFIEDDATE",timestamp);
        JSONObject whereKeys = new JSONObject();
        whereKeys.put("ID",objid);
        // 执行mapper更新
        HashMap mTableMap = new HashMap();
        mTableMap.put("tableName",mTable);
        mTableMap.put("setKeys",setKeys);
        mTableMap.put("whereKeys",whereKeys);
        int count = queryService.commandUpdate(mTableMap);
        if (count == 0){
            throw new NDSException(Resources.getMessage("当前记录已不存在！",querySession.getLocale()));
        }
    }

    /**
     * 更新子表
     * @param tableName 明细表表名
     * @param joItem 明细表参数
     * @param querySession querySession
     * @param timestamp 系统时间
     * @param i 当前循环序号
     * @return JSONObject
     */
    private JSONObject updateStable(String tableName,JSONArray joItem,QuerySession querySession,Timestamp timestamp,int i){
        JSONObject dataJson = new JSONObject();
        JSONObject setKeys = joItem.getJSONObject(i);
        // 更新明细表
        try {
            setKeys.put("MODIFIERID", querySession.getUser().getId().longValue());
            setKeys.put("MODIFIEDDATE",timestamp);
            JSONObject whereKeys = new JSONObject();
            whereKeys.put("ID",joItem.getJSONObject(i).getLong("ID"));
            // 执行mapper更新
            HashMap sTableMap = new HashMap();
            sTableMap.put("tableName",tableName);
            sTableMap.put("setKeys",setKeys);
            sTableMap.put("whereKeys",whereKeys);
            int count = queryService.commandUpdate(sTableMap);
            if (count == 0) {
                throw new NDSException(Resources.getMessage("当前记录已不存在！", querySession.getLocale()));
            }
        }catch (NDSException e){
            // 将错误信息存入dataArrayJson中
            dataJson = getData(e,joItem.getJSONObject(i).getLong("ID"));
        }
        return dataJson;
    }

    /**
     * 获取明细表更新错误信息并插入dataJson
     * @param e 异常信息
     * @param itemId 明细ID
     * @return JSONObject
     */
    private JSONObject getData(NDSException e,Long itemId){
        JSONObject dataJson = new JSONObject();
        dataJson.put("id", itemId);
        dataJson.put("code", "-1");
        dataJson.put("message", e.toJsonException().get("msg"));
        return dataJson;
    }

    /**
     * 获取明细表新增错误信息并插入dataJson
     * @param e 异常信息
     * @return JSONObject
     */
    private JSONObject getData(NDSException e){
        JSONObject dataJson = new JSONObject();
        dataJson.put("code", "-1");
        dataJson.put("message", e.toJsonException().get("msg"));
        return dataJson;
    }

}
